home *** CD-ROM | disk | FTP | other *** search
- void SIO_SEROUT (unsigned char byte, int cmd)
- {
- checksum += (unsigned char)byte;
- while (checksum > 255)
- checksum = checksum - 255;
-
- #ifdef DEBUG
- printf ("SIO_SEROUT: byte = %x, checksum = %x, cmd = %d\n",
- byte, checksum, cmd);
- #endif
-
- if (cmd)
- {
- CommandFrame[ncmd++] = byte;
- if (ncmd == 5)
- {
- Command_Frame ();
-
- offst = 0;
- checksum = 0;
- ncmd = 0;
- }
- else
- {
- DELAYED_SEROUT_IRQ = 1;
- }
-
- if (CommandFrame[0] == 0)
- ncmd = 0;
- }
- else if (sio_state == SIO_Put)
- {
- DataBuffer[buffer_offset++] = byte;
- if (buffer_offset == 130)
- {
- int sector;
- int dskno;
- int i;
-
- checksum = 0;
-
- for (i=1;i<129;i++)
- {
- checksum += (unsigned char)DataBuffer[i];
- while (checksum > 255)
- checksum = checksum - 255;
- }
-
- if (checksum != DataBuffer[129])
- {
- printf ("Direct SIO Write Error\n");
- printf ("Calculated Checksum = %x\n", checksum);
- printf ("Actual Checksum = %x\n", DataBuffer[129]);
- exit (1);
- }
-
- dskno = CommandFrame[0] - 0x31;
- sector = CommandFrame[2] + CommandFrame[3] * 256;
-
- #ifdef DEBUG
- printf ("Sector: %d(%x)\n", sector, sector);
- #endif
-
- SeekSector (dskno, sector);
-
- write (disk[dskno], &DataBuffer[1], 128);
- DataBuffer[buffer_offset] = 0x41; /* ACK */
- DataBuffer[buffer_offset+1] = 0x43; /* OPERATION COMPLETE */
- buffer_size = buffer_offset + 2;
- DELAYED_SEROUT_IRQ = 1;
- DELAYED_XMTDONE_IRQ = 3;
- DELAYED_SERIN_IRQ = 7;
- DELAYED_XMTDONE_IRQ = 5;
- DELAYED_SERIN_IRQ = 150;
- }
- else
- {
- DELAYED_SEROUT_IRQ = 4;
- }
- }
- else
- {
- DELAYED_SEROUT_IRQ = 1;
- ncmd = 0;
- }
- }
-
- int SIO_SERIN (void)
- {
- int byte;
-
- if (buffer_offset < buffer_size)
- {
- byte = (int)DataBuffer[buffer_offset++];
-
- #ifdef DEBUG
- printf ("SERIN: byte = %x\n", byte);
- #endif
-
- if (buffer_offset < buffer_size)
- {
- #ifdef DEBUG
- printf ("Setting SERIN Interrupt again\n");
- #endif
- DELAYED_SERIN_IRQ = 3;
- DELAYED_SERIN_IRQ = 4;
- }
- }
-
- return byte;
- }
-
- void SIO (void)
- {
- /* UBYTE DDEVIC = memory[0x0300]; */
- UBYTE DUNIT = memory[0x0301];
- UBYTE DCOMND = memory[0x0302];
- /* UBYTE DSTATS = memory[0x0303]; */
- UBYTE DBUFLO = memory[0x0304];
- UBYTE DBUFHI = memory[0x0305];
- /* UBYTE DTIMLO = memory[0x0306]; */
- UBYTE DBYTLO = memory[0x0308];
- UBYTE DBYTHI = memory[0x0309];
- UBYTE DAUX1 = memory[0x030a];
- UBYTE DAUX2 = memory[0x030b];
-
- int sector;
- int buffer;
- int count;
- int i;
-
- if (drive_status[DUNIT-1] != Off)
- {
- if (disk[DUNIT-1] != -1)
- {
- int offset;
-
- sector = DAUX1 + DAUX2 * 256;
- buffer = DBUFLO + DBUFHI * 256;
- count = DBYTLO + DBYTHI * 256;
-
- switch (format[DUNIT-1])
- {
- case XFD :
- offset = (sector-1)*128+0;
- break;
- case ATR :
- if (sector < 4)
- offset = (sector-1) * 128 + 16;
- else
- offset = (sector - 1) * sectorsize[DUNIT-1] + 16;
- /*
- offset = 3*128 + (sector-4) * sectorsize[DUNIT-1] + 16;
- */
- break;
- default :
- printf ("Fatal Error in atari_sio.c\n");
- Atari800_Exit (FALSE);
- exit (1);
- }
-
- lseek (disk[DUNIT-1], offset, SEEK_SET);
-
- #ifdef DEBUG
- printf ("SIO: DCOMND = %x, SECTOR = %d, BUFADR = %x, BUFLEN = %d\n",
- DCOMND, sector, buffer, count);
- #endif
-
- switch (DCOMND)
- {
- case 0x50 :
- case 0x57 :
- if (drive_status[DUNIT-1] == ReadWrite)
- {
- write (disk[DUNIT-1], &memory[buffer], count);
- regY = 1;
- ClrN;
- }
- else
- {
- regY = 146;
- SetN;
- }
- break;
- case 0x52 :
- read (disk[DUNIT-1], &memory[buffer], count);
- regY = 1;
- ClrN;
- break;
- case 0x21 : /* Single Density Format */
- case 0x22 : /* Duel Density Format */
- case 0x66 : /* US Doubler Format - I think! */
- regY = 1;
- ClrN;
- break;
- /*
- Status Request from Atari 400/800 Technical Reference Notes
-
- DVSTAT + 0 Command Status
- DVSTAT + 1 Hardware Status
- DVSTAT + 2 Timeout
- DVSTAT + 3 Unused
-
- Command Status Bits
-
- Bit 0 = 1 indicates an invalid command frame was received
- Bit 1 = 1 indicates an invalid data frame was received
- Bit 2 = 1 indicates that a PUT operation was unsuccessful
- Bit 3 = 1 indicates that the diskete is write protected
- Bit 4 = 1 indicates active/standby
-
- plus
-
- Bit 5 = 1 indicates double density
- Bit 7 = 1 indicates duel density disk (1050 format)
- */
- case 0x53 : /* Get Status */
- /*
- for (i=0;i<count;i++)
- {
- if (sectorsize[DUNIT-1] == 256)
- memory[buffer+i] = 32 + 16;
- else
- memory[buffer+i] = 16;
- }
- */
- if (count!=4) {
- regY = 146;
- SetN;
- break;
- }
- if (drive_status[DUNIT-1] == ReadWrite) {
- memory[buffer]=(sectorsize[DUNIT-1] == 256)?(32+16):(16);
- memory[buffer+1]=192;
- } else {
- memory[buffer]=(sectorsize[DUNIT-1] == 256)?(32):(0);
- memory[buffer+1]=64;
- }
- if (sectorcount[DUNIT-1]==1040) memory[buffer]|=128;
- memory[buffer+2]=1;
- memory[buffer+3]=0;
- regY = 1;
- ClrN;
- break;
- default :
- printf ("SIO: DCOMND = %0x\n", DCOMND);
- regY = 146;
- SetN;
- break;
- }
- }
- else
- {
- regY = 146;
- SetN;
- }
- }
- else
- {
- regY = 138;
- SetN;
- }
-
- memory[0x0303] = regY;
- }
- /*
- printf ("Command frame: %02x %02x %02x %02x %02x\n",
- CommandFrame[0], CommandFrame[1], CommandFrame[2],
- CommandFrame[3], CommandFrame[4]);
- */
-
- switch (CommandFrame[1]) {
- case 'R' : /* Read */
- {
- int sector;
- int dskno;
- int i;
- int checksum;
-
- dskno = CommandFrame[0] - 0x31;
- sector = CommandFrame[2] + CommandFrame[3] * 256;
- SeekSector (dskno, sector);
-
- DataBuffer[0] = 0x41; /* ACK */
- DataBuffer[1] = 0x43; /* OPERATION COMPLETE */
-
- read (disk[dskno], &DataBuffer[2], 128);
- checksum = 0;
- for (i=2;i<130;i++) {
- checksum += (unsigned char)(DataBuffer[i]);
- while (checksum > 255)
- checksum = checksum - 255;
- }
- DataBuffer[130] = checksum;
- ExpectedBytes = 131;
- DataIndex = 0;
- DELAYED_SERIN_IRQ += SERIN_INTERVAL+312;
- }
- break;
- case 'S' : /* Status */
- #ifdef DEBUG
- printf ("Status command\n");
- #endif
- DataBuffer[0] = 0x41; /* ACK */
- DataBuffer[1] = 0x43; /* OPERATION COMPLETE */
-
- /* Should be really done in a different way */
- DataBuffer[2] = 0x10; /* 2ea */
- DataBuffer[3] = 0x00; /* 2eb */
- DataBuffer[4] = 0x01; /* 2ec */
- DataBuffer[5] = 0x00; /* 2ed */
- DataBuffer[6] = 0x11; /* Checksum */
-
- ExpectedBytes = 7;
- DataIndex = 0;
- DELAYED_SERIN_IRQ += SERIN_INTERVAL;
- break;
- case 'W' : /* Write with verify */
- case 'P' : /* Put without verify */
- DataBuffer[0] = 0x41; /* ACK */
-
- ExpectedBytes = 1;
- DataIndex = 0;
-
- DELAYED_SERIN_IRQ += SERIN_INTERVAL;
- break;
- case '!' : /* Format */
- printf ("Format command\n");
- break;
- case 'T' : /* Read Address */
- printf ("Read Address command\n");
- break;
- case 'Q' : /* Read Spin */
- printf ("Read Spin command\n");
- break;
- case 'U' : /* Motor On */
- printf ("Motor On command\n");
- break;
- case 'V' : /* Verify Sector */
- printf ("Verify Sector\n");
- break;
- default :
- printf ("Command frame: %02x %02x %02x %02x %02x\n",
- CommandFrame[0], CommandFrame[1], CommandFrame[2],
- CommandFrame[3], CommandFrame[4]);
- break;
- }
- }
-
-